using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;

using System.Drawing;
using System.Drawing.Drawing2D;

using System.Windows.Forms;
using Athena;
using Athena.Tools;
using Athena.Objects;
using Athena.Core;

using WeifenLuo.WinFormsUI.Docking;

namespace Athena.Plugins
{
    public partial class DBPlugin : IGUITool
    {

        private static DBPlugin _oInstance = new DBPlugin();

        public static DBPlugin Instance
        {
            get { return _oInstance; }
        }

        protected bool _Opened = false;

        public DBPlugin()
        {
            _bRequiresNewToolWindow = false;
            _bHasContextMenuItems = true;
            _bHasMenuItems = true;

            InitializeComponent();

            Text = "Database";
            ToolManager.Instance.RegisterTool(Text, "Load and Save to the parts database", this);
        }
        public override void SetupDockPanel(WeifenLuo.WinFormsUI.Docking.DockPanel oPanel)
        {
            this.DockPanel = oPanel;
            //if (oPanel != null)
            //    oPanel.Size = new System.Drawing.Size(50, 50);
            //DockState = DockState.Float;
        }
        public override void SetupToolStrip(ToolStrip oStrip)
        {
            ToolStripButton oButton = new ToolStripButton();
            oButton.Text = "Database";
            oButton.ToolTipText = "Lookup and store parts or species into/from the database";
            oButton.Click += new EventHandler(Show_Clicked);
            oStrip.Items.Add(oButton);
            _bHasContextMenuItems = true;
            _bHasMenuItems = false;
            _bRequiresNewToolWindow = false;
        }

        public void Show_Clicked(object sender, EventArgs e)
        {
            if (CurrentModel.BackEndModel != null)
            {
                try
                {
                    foreach (IDrawable id in CurrentModel.Selected)
                    {
                        if (id.Item is Node)
                        {
                            List<Node> nodes = IO.SQL.Substitutes((Node)id.Item);
                            Instance.PopulateList(nodes);
                            Instance.ShowHide_Click(null, null);
                            break;
                        }
                    }
                }
                catch (Exception)
                {
                    Utility.SetMessage("No substitution found ...");
                }
            }
        }

        public override void ShowHide_Click(object sender, EventArgs e)
        {
            if (IsHidden)
            {
                DockState = DockState.Float;
                Show();
            }
            else
            {
                Hide();
            }
        }
        void MainForm_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
        {
            this.Hide();
            e.Cancel = true;
        }

        private List<Node> _nodeList = new List<Node>();
        public void PopulateList(List<Node> nodes)
        {
            listBox1.Items.Clear();
            foreach (Node n in nodes)
                listBox1.Items.Add(string.Format("{0}     ({1}, id: {2})", n.ID, n.ItemType, n.DBID));
            _nodeList = nodes;
        }


        public override void SetupContextMenu(ToolStripMenuItem oStrip)
        {
            foreach (ToolCommand command in _oCommands)
            {
                oStrip.DropDownItems.Add(command.ToMenuItem());
            }
        }
        public override bool Handles(List<Type> oTypes)
        {
            bool bResult = true;
            foreach (Type t in oTypes)
            {
                bResult &= Handles(t);
                if (!bResult) return false;
            }
            return bResult;
        }

        private bool Handles(Type t)
        {
            return Utility.IsTypeNoAbstract(typeof(Athena.Objects.IDrawable), t);
        }

        class ToolCommand
        {
            private string _sCommand;

            public string Command
            {
                get { return _sCommand; }
                set { _sCommand = value; }
            }

            private Bitmap _Icon;
            public Bitmap Icon
            {
                get
                {
                    return _Icon;
                }
                set
                {
                    _Icon = value;
                }
            }

            private string _Description;
            public string Description
            {
                get
                {
                    return _Description;
                }
                set
                {
                    _Description = value;
                }
            }


            public ToolCommand()
            {
                _sCommand = null;
                _Icon = null;
            }

            /// <summary>
            /// Initializes a new instance of the ToolCommand class.
            /// </summary>
            /// <param name="sCommand"></param>
            /// <param name="icon"></param>
            /// <param name="description"></param>
            public ToolCommand(string sCommand, Bitmap icon, string description)
            {
                _sCommand = sCommand;
                _Icon = icon;
                _Description = description;
            }

            public ToolStripItem ToMenuItem()
            {
                if (_Icon == null && _sCommand == null)
                {
                    return new ToolStripSeparator();
                }
                else
                {

                    ToolStripMenuItem oItem = new ToolStripMenuItem(_sCommand);
                    if (_Icon != null)
                        oItem.Image = _Icon;
                    oItem.Tag = _sCommand;
                    oItem.ToolTipText = _Description;
                    oItem.ImageScaling = ToolStripItemImageScaling.None;
                    oItem.Click += new EventHandler(CommandExecute);
                    return oItem;
                }
            }

            public ToolStripItem ToToolStripButton()
            {
                if (_Icon == null)
                {
                    return new ToolStripSeparator();
                }
                else
                {
                    ToolStripButton oButton = new ToolStripButton(_sCommand);
                    if (_Icon != null)
                        oButton.Image = _Icon;
                    oButton.Checked = true;
                    oButton.DisplayStyle = ToolStripItemDisplayStyle.Image;
                    oButton.Tag = _sCommand;
                    oButton.ImageScaling = ToolStripItemImageScaling.None;
                    oButton.ToolTipText = _Description;
                    oButton.Click += new EventHandler(CommandExecute);
                    return oButton;
                }
            }

            void CommandExecute(object sender, EventArgs e)
            {
                string sTag = "";
                if (sender is ToolStripButton)
                    sTag = (string)((ToolStripButton)sender).Tag;
                else if (sender is ToolStripMenuItem)
                    sTag = (string)((ToolStripMenuItem)sender).Tag;
                else
                    return;

                //since all are connectors, the following methods can be applied
                switch (sTag)
                {
                    case "Save":
                        //HistoryManager.History.SetControllPoint("Saved items to Database");
                        foreach (IDrawable id in CurrentModel.Selected)
                        {
                            try
                            {
                                IO.SQL.InsertItem(id.Item);
                            }
                            catch (Exception) { }
                        }
                        Utility.Refresh();
                        break;
                    case "Load Connections":
                        if (CurrentModel.BackEndModel != null)
                        {
                            HistoryManager.History.SetControllPoint("Loaded Connections from Database");
                            foreach (Connector c in IO.SQL.LoadConnectionsFromDB(CurrentModel.Selected))
                            {
                                try
                                {
                                    if (!CurrentModel.BackEndModel.Contains(c.Name))
                                    {
                                        CurrentModel.AddToModel(c);
                                    }
                                }
                                catch (Exception) { }
                            }
                        }
                        Utility.Refresh();
                        break;
                    case "Substitute":
                        if (CurrentModel.BackEndModel != null)
                        {
                            try
                            {
                                foreach (IDrawable id in CurrentModel.Selected)
                                {
                                    if (id.Item is Node)
                                    {
                                        List<Node> nodes = IO.SQL.Substitutes((Node)id.Item);
                                        Instance.PopulateList(nodes);
                                        Instance.ShowHide_Click(null, null);
                                        break;
                                    }
                                }
                            }
                            catch (Exception)
                            {
                                Utility.SetMessage("No substitution found ...");
                            }
                        }
                        Utility.Refresh();
                        break;
                    default:
                        break;
                }
            }


        }

        static ToolCommand[] _oCommands = new ToolCommand[]
        {
            //new ToolCommand("Initialize", null , "Initialize the database"),
            //new ToolCommand("Close", null , "Close the database"),
            new ToolCommand("Save", null , "Insert a this component into the database"),
            new ToolCommand("Load Connections", null , "Load all connections for these parts from the database"),
            new ToolCommand("Substitute", null , "Find a fitting substitute for this node")
            
        };

        /// <summary>
        /// What happens when the Load button is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            if (listBox1.SelectedIndex < 0) return;

            foreach (IDrawable id in CurrentModel.Selected)
            {
                if (id.Item is Node && listBox1.SelectedIndex >= 0 &&
                    _nodeList.Count > listBox1.SelectedIndex && _nodeList[listBox1.SelectedIndex] is Node)
                {
                    id.Item.DBID = (_nodeList[listBox1.SelectedIndex].DBID);
                    id.Item.ID = (_nodeList[listBox1.SelectedIndex].ID);
                    id.Item.Mirror(_nodeList[listBox1.SelectedIndex]);
                    break;
                }
            }
            Instance.ShowHide_Click(null, null);
            Utility.Refresh();
        }

    }
}